#!BPY
"""
Name: 'Ralf Export'
Blender: 245
Group: 'Export'
Tooltip: 'Ralf test exporter'
"""

import Blender
import bpy

def write(filename):
    out = file(filename, "w")
    out.write("RB1\n") # header signature (ralf blender v1)
    scene = bpy.data.scenes.active
    for obj in scene.objects:
        if obj.type == "Mesh":
            print "Process %s (%s)" % (obj.name, obj.type)
            processMesh(out, obj.getData(mesh=True))
        else:
            print "Ignore %s (%s)" % (obj.name, obj.type)

def processMesh(out, mesh):
    out.write("OBJ:%s\n" % mesh.name)

    # Faces are either triangles or quads.
    # Moreover, each face points to its vertex with its
    # own UV params whereas we want merged UV coords.
    # Save (x,y,z,u,v) in a dict and merge similar
    # points, then re-organize the indices
    faces = []
    vertices = {}
    has_uvco = mesh.vertexUV # F9 > Mesh > Sticky > Make/Delete
    for f in mesh.faces:
        v = f.verts
        processTriangle(v[0], v[1], v[2], vertices, faces, has_uvco)
        if len(v) == 4: # extract second triangle from quad
            processTriangle(v[0], v[2], v[3], vertices, faces, has_uvco)

    vertices_array = list(vertices.values())
    for k, v in vertices.iteritems():
        vertices_array[v] = k
    out.write("Vert %d" % len(vertices_array))
    for v in vertices_array:
        out.write(", %.3f %.3f %.3f" % (v[0], v[1], v[2]))
    out.write("\n")

    if has_uvco:
        out.write("UV %d" % len(vertices_array))
        for v in vertices_array:
            out.write(", %.3f %.3f" % (v[3], v[4]))
        out.write("\n")
        
    out.write("Faces %d" % len(faces))
    for f in faces:
        out.write(", %d %d %d" % (f[0], f[1], f[2]))
    out.write("\n")

def processTriangle(p0, p1, p2, vertices, faces, has_uvco):
    """
    Add new triangle to faces, using vertex indices.
    Either reuse existing vertices or add new ones.
    """
    i0 = addVertex(p0, vertices, has_uvco)
    i1 = addVertex(p1, vertices, has_uvco)
    i2 = addVertex(p2, vertices, has_uvco)
    faces.append((i0, i1, i2))

def addVertex(p, vertices, has_uvco):
    """
    Add vertex (p.x/y/z) in vertices and returns its index (starting at 0)
    If vertex is already present, returns existing index.
    """
    if has_uvco:
        v = (p.co.x, p.co.y, p.co.z, p.uvco.x, p.uvco.y)
    else:
        v = (p.co.x, p.co.y, p.co.z)
    if v in vertices:
        return vertices[v]  # index of v
    # otherwise add it. key is (x,y,z), value is index
    vertices[v] = i = len(vertices) # index starts at 0
    return i

Blender.Window.FileSelector(write, "Export")
